package com.example.demo01.demo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.util.List;
import java.util.Map;

/**
 * @Description: 任务参数配置
 * @author: zhangshiwei
 * @date: 2021年10月14日 14:19
 */
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class JobParamConfigBO {

    /**
     * 数据预处理
     */
    private DataProcessingBO dataProcessing;

    /**
     * 调优参数配置
     */
    private List<Algorithm> algrithms;

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Algorithm {

        /**
         * 算法名
         */
        private String algrithmName;

        /**
         * 参数信息
         */
        private Map<String, Object> algrithmParams;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class DataProcessingBO {

        /**
         * 数据加载
         */
        private LoadBO load;

        /**
         * 数据切分
         */
        private SplitBO split;

        /**
         * 上采样
         */
        private SampleBO upSample;

        /**
         * 下采样
         */
        private SampleBO downSample;

        /**
         * 缺失值填充
         */
        @JsonProperty("imputer")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private List<ImputerBO> imputer;

        /**
         * 字段类型转换配置
         */
        private ChangeDataTypeBO changeDataType;

        /**
         * 数据过滤处理
         */
        private FilterBO filter;

        /**
         * 独热编码配置，仅支持字符串类型的，且字符串类型必须设置
         */
        @JsonProperty("oneHot")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private List<OneHotBO> oneHot;

        /**
         * 二值化配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("binarizer")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private BinarizerBO binarizer;

        /**
         * 分位数离散化配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("quantileDiscretizer")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private List<QuantileDiscretizerBO> quantileDiscretizer;

        /**
         * 特性分桶配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("bucketizer")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private BucketizerBO bucketizer;

        /**
         * 尺度变换配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("changeScale")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private ChangeScaleBO changeScale;

        /**
         * 归一化配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("normalization")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private List<NormalizationBO> normalization;

        /**
         * 标准化配置，仅支持费字符串类型字段配置
         */
        @JsonProperty("standardization")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private List<StandardizationBO> standardization;

        /**
         * 滑动窗口配置，仅时序预测模型需要配置
         */
        @JsonProperty("slideWindow")
        @JsonInclude(JsonInclude.Include.ALWAYS)
        private SlideWindow slideWindow;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class SlideWindow {

        /**
         * 特征长度
         */
        private Integer featureLen;

        /**
         * 标签长度
         */
        private Integer labelLen;

        /**
         * 偏移量
         */
        private Integer offset;

        /**
         * 滑动距离
         */
        private Integer slideDistance;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class LoadBO {

        /**
         * 数据集编码
         */
        private String dataCode;

        /**
         * 数据集版本
         */
        private Integer dataVersion;

        /**
         * 标签列列名
         */
        private String labelCol;

        /**
         * 特征列
         */
        private List<String> featureCols;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class SplitBO {

        /**
         * 测试集比例
         */
        private Double testRatio;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class SampleBO {

        /**
         * 采样标签
         */
        private List<String> sampleLabels;

        /**
         * 目标标签
         */
        private List<String> targetLabels;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class ImputerBO {

        /**
         * 索引，字符串
         */
        private String index;

        /**
         * 缺失值参数
         */
        private ParamsBO params;

        @Getter
        @Setter
        @ToString
        @NoArgsConstructor
        @AllArgsConstructor
        @Builder
        public static class ParamsBO {

            /**
             * 要进行处理的列
             */
            private String inputCol;

            /**
             * 缺失值判断
             */
            private Integer missingType;

            /**
             * 自定义缺失值
             */
            @JsonProperty("customMissingValue")
            @JsonInclude(JsonInclude.Include.NON_NULL)
            private Object customMissingValue;

            /**
             * 填充策略
             */
            private Integer strategy;

            /**
             * 自定义填充值
             */
            @JsonProperty("customFillingValue")
            @JsonInclude(JsonInclude.Include.NON_NULL)
            private Object customFillingValue;
        }
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class ChangeDataTypeBO {

        /**
         * 要进行数据类型转换的列
         */
        private List<String> inputCols;

        /**
         * 转换后的数据类型
         */
        private List<Integer> newDtypeArray;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class FilterBO {

        /**
         * 数据预处理表达式
         */
        private String condition;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class OneHotBO {

        /**
         * 索引，从1开始依次递增
         */
        private String index;

        /**
         * 要进行独热编码处理的列，仅支持字符串类型的，且字符串类型必须设置
         */
        private ConversionParamBO params;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class BinarizerBO {

        /**
         * 要进行处理的列
         */
        private List<String> inputCols;

        /**
         * 每列的阈值。大于阈值的变成1.0，小于阈值的变成0.0
         */
        private List<Double> thresholds;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class QuantileDiscretizerBO {


        /**
         * 索引，从1开始依次递增
         */
        private String index;

        /**
         * 分位数离散化配置的列和分桶个数，仅支持费字符串类型字段配置
         */
        private ParamsBO params;

        @Getter
        @Setter
        @ToString
        @NoArgsConstructor
        @AllArgsConstructor
        @Builder
        public static class ParamsBO {

            /**
             * 要进行处理的列
             */
            private String inputCol;

            /**
             * 分桶的个数
             */
            private Integer numBuckets;
        }
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class BucketizerBO {

        /**
         * 进行特性分桶配置的列，仅支持费字符串类型字段配置
         */
        private List<String> inputCols;

        /**
         * 每列的分桶分割点
         */
        private List<List<Double>> splitsArray;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class ChangeScaleBO {

        /**
         * 要进行处理的列
         */
        private List<String> inputCols;

        /**
         * 每列的尺度转换方法
         */
        private List<Integer> scalesArray;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class NormalizationBO {

        /**
         * 索引，从1开始依次递增
         */
        private String index;

        /**
         * 归一化配置的列
         */
        private ConversionParamBO params;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class StandardizationBO {

        /**
         * 索引，从1开始依次递增
         */
        private String index;

        /**
         * 标准化配置的列
         */
        private ConversionParamBO params;
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class ConversionParamBO {

        /**
         * 字段
         */
        private String inputCol;
    }
}
